package cn.bluethink.eguan.core.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.bluethink.eguan.core.entity.EgTaskEntity;
import cn.bluethink.eguan.core.mapper.EgTaskMapper;
import cn.bluethink.eguan.filter.NameFilter;
import cn.bluethink.eguan.model.core.EgOType;
import cn.bluethink.eguan.model.core.EgTask;
import cn.bluethink.eguan.model.core.EgTaskStatus;
import cn.bluethink.eguan.model.core.EgUser;
import cn.bluethink.eguan.result.PageInfo;
import cn.bluethink.eguan.utils.IdMakerUtils;
import tk.mybatis.mapper.entity.Example;

@Service
public class EgTaskService {

    @Autowired
    private EgTaskMapper taskMapper;

    @Autowired
    private EgUserService userService;

    @Autowired
    private EgStaffService staffService;

    @Autowired
    private EgMemberService memberService;

    private IdMakerUtils idUtil = new IdMakerUtils();

    /**
     * 发布任务
     * 
     * @param task
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public EgTask create(EgTask task) throws Exception {
        // 1、Id生成器生成主键Id
        task.setId(idUtil.nextId());
        // 2、判断是否符合任务要求，不符合返回null
        if (!task.isValidate()) {
            return null;
        }
        // 3、将任务模型转换为任务实体
        EgTaskEntity taskEntity = new EgTaskEntity(task, true);
        taskEntity.setCtime(new Date());
        taskEntity.setDelFlag(0);
        // 4、新增任务
        if (taskMapper.insertSelective(taskEntity) == 0) {
            return null;
        }
        task.setId(taskEntity.getTid());
        return task;
    }

    /**
     * 修改任务
     * 
     * @param task
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public EgTask update(EgTask task) throws Exception {
        // 1、任务模型转换为任务实体
        EgTaskEntity taskEntity = new EgTaskEntity(task, false);
        // 2、更新通用任务
        if (taskMapper.updateTask(taskEntity) == 0) {
            return null;
        }
        return task;
    }

    /**
     * 删除任务(修改为逻辑删除)
     * 
     * @param id
     * @param otype
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public Long remove(Long id, Integer otype) throws Exception {
        // 构造删除条件
        Example example = new Example(EgTaskEntity.class);
        example.and().andEqualTo("tid", id).andEqualTo("otype", otype);
        // 构造需要更新的字段 del_flag
        EgTaskEntity entity = new EgTaskEntity();
        entity.setDelFlag(1);
        // 逻辑删除任务
        if (taskMapper.updateByExampleSelective(entity, example) > 0)
            return id;
        return 0L;
    }

    /**
     * 根据所在位置 逻辑 删除 在其中发布的任务
     * 
     * @param posOid
     * @param posOtype
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public Boolean removeByPos(Long posOid, Integer posOtype) throws Exception {
        // 构造删除条件
        Example example = new Example(EgTaskEntity.class);
        example.and().andEqualTo("posOid", posOid).andEqualTo("posOtype", posOtype);
        // 构造需要更新的字段 del_flag
        EgTaskEntity entity = new EgTaskEntity();
        entity.setDelFlag(1);
        // 根据pos逻辑删除对应的任务
        if (taskMapper.updateByExampleSelective(entity, example) > 0)
            return true;
        return false;
    }

    /**
     * 查询任务详情，包括发布者信息
     * 
     * @param id
     * @param otype
     * @return
     * @throws Exception
     */
    public EgTask detail(Long id, Integer otype) throws Exception {
        Example example = new Example(EgTaskEntity.class);
        example.and().andEqualTo("tid", id).andEqualTo("otype", otype).andEqualTo("delFlag", 0);
        EgTaskEntity entity = taskMapper.selectOneByExample(example);
        if (entity != null && entity.getTid() != null) {
            EgTask task = entity.createEgTask();
            // 获取用户的基本要素
            EgUser cuser = userService.getUserBasic(entity.getCuid());
            if (cuser != null) {
                task.setCuser(cuser);
            }
            return task;
        }
        return null;
    }

    /**
     * 更新审核状态
     * 
     * @param checkStatus
     * @param tid
     * @return
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public int updateCheckStatus(Integer checkStatus, Long tid) {
        EgTaskEntity taskEntity = new EgTaskEntity();
        taskEntity.setTid(tid);
        taskEntity.setCheckStatus(checkStatus);
        int result = taskMapper.updateByPrimaryKeySelective(taskEntity);
        return result == 0 ? 0 : result;
    }

    /**
     * 根据条件查询任务列表
     * 
     * @param posOid
     * @param posOtype
     * @param status
     * @return
     * @throws Exception
     */
    public List<EgTask> query(Long posOid, Integer posOtype, Integer status) throws Exception {
        Example example = buildQueryCondition(posOid, posOtype, status);
        List<EgTaskEntity> entities = taskMapper.selectByExample(example);
        List<EgTask> tasks = new ArrayList<>();
        if (entities != null && entities.size() > 0) {
            tasks = entities.stream().map(e -> e.createEgTask()).collect(Collectors.toList());
        }
        return tasks;
    }

    /**
     * 根据悬赏任务的ID(获取发布地)获取用户列表(门派成员/驿馆伙计) 用于悬赏任务指派
     * 
     * @param task
     * @param filter
     * @return
     * @throws Exception
     */
    public PageInfo<EgUser> users(EgTask task, NameFilter filter) throws Exception {
        // 获取该悬赏任务的发布地
        Integer otype = task.getPos().getType().getOtid();
        Long oid = task.getPos().getId();
        PageInfo<EgUser> result = new PageInfo<EgUser>();
        filter.setId(oid);
        switch (otype) {
        case EgOType.FACTION:
            result = memberService.query(filter, false);
            break;
        case EgOType.TAVERN:
            result = staffService.query(filter, false);
            break;
        default:
            break;
        }
        return result;
    }

    /**
     * 构造任务查询条件
     * 
     * @param posOid
     * @param posOtype
     * @param status
     * @return
     * @throws Exception
     */
    private Example buildQueryCondition(Long posOid, Integer posOtype, Integer status) throws Exception {
        Example example = new Example(EgTaskEntity.class);
        // 1、判断pos是否为空
        if (posOid != null && posOtype != null) {
            // 2、如果pos不为空，并且posOid为0/posOtyp为0，此时设置位置Id和type为0（江湖）
            if (posOid == 0 || posOtype == 0) {
                posOid = 0L;
                posOtype = 0;
            }
            example.and().andEqualTo("posOid", posOid).andEqualTo("posOtype", posOtype);
        }
        // 3、判断status是否为空
        if (status != null && status > 0) {
            // 4、如果status不为空并且是未完成状态时，查询当前状态及延误状态的任务列表
            if (status != EgTaskStatus.STATUS_FINISH) {
                List<Integer> statusCondition = new ArrayList<>();
                statusCondition.add(status);
                statusCondition.add(status + 1);
                example.and().andIn("status", statusCondition);
            } else {
                example.and().andEqualTo("status", status);
            }
        }
        // 5、设置排序条件（按照创建日期由近及远）
        example.setOrderByClause("ctime desc");
        return example;
    }

    /**
     * 定时更新当前工作任务状态为已延误/延误进行/延误完成/
     * 
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    @Scheduled(cron = "${task.date}")
    public void updateStatusToDelay() throws Exception {
        taskMapper.updateStatusToDelay();
    }

    /**
     * 定时清除del_flag为1 的悬赏任务和工作任务
     * 
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    @Scheduled(cron = "${task.date}")
    public void delTasks() throws Exception {
        // 构造删除条件
        Example example = new Example(EgTaskEntity.class);
        example.and().andEqualTo("delFlag", 1);
        taskMapper.deleteByExample(example);
    }

    /**
     * 根据任务的类型以及任务的发布地ID列表查询
     * 
     * @param otype
     * @param posOids
     * @return
     * @throws Exception
     */
    public List<EgTask> queryByOtypeAndPos(Integer otype, Set<Long> posOids) throws Exception {
        // 构造删除条件
        Example example = new Example(EgTaskEntity.class);
        example.and().andEqualTo("otype", otype).andIn("posOid", posOids).andEqualTo("delFlag", 0);
        List<EgTaskEntity> entities = taskMapper.selectByExample(example);
        // 创建返回结果
        List<EgTask> tasks = new ArrayList<>();
        if (entities != null && entities.size() > 0) {
            tasks = entities.stream().map(e -> e.createEgTask()).collect(Collectors.toList());
        }
        return tasks;
    }

    /**
     * 批量逻辑删除通用任务列表
     * 
     * @param taskList
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public Boolean deltaskList(List<EgTask> taskList) throws Exception {
        List<EgTaskEntity> entities = new ArrayList<>();
        for (EgTask task : taskList) {
            EgTaskEntity entity = new EgTaskEntity(task, false);
            entities.add(entity);
        }
        int upCount = taskMapper.updateTaskList(entities);
        return upCount > 0 ? true : false;
    }
}
